/**
 * @file face_detect.cpp
 * @author 逆流 (1171267147@qq.com)
 * @brief opencv实现人脸检测
 * @version 0.1
 * @date 2024-09-26
 *
 * @copyright Copyright (c) 2024
 *
 */

// 使用opencv实现人脸检测功能
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>

#include "env.h"
#include "opencv2/highgui.hpp"

int main() {
    // 加载人脸检测的Haar级联分类器
    cv::CascadeClassifier face_cascade;
    auto                  face_cascade_file = kResourcesDir + "haarcascades/haarcascade_frontalface_default.xml";
    if (!face_cascade.load(face_cascade_file)) {
        std::cerr << "无法加载级联分类器" << '\n';
        return -1;
    }

    // 打开视频文件
    auto             video_file = kResourcesDir + "face_test_01.mp4";
    cv::VideoCapture cap(video_file);
    if (!cap.isOpened()) {
        std::cerr << "无法打开摄像头" << '\n';
        return -1;
    }

    cv::Mat frame;

    while (true) {
        cap >> frame;  // 从摄像头读取一帧

        if (frame.empty()) {
            std::cerr << "无法读取帧" << '\n';
            break;
        }

        // 将帧转换为灰度图像
        cv::Mat gray;
        cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);

        // 检测人脸
        std::vector<cv::Rect> faces;
        face_cascade.detectMultiScale(gray, faces, 1.1, 3, 0, cv::Size(30, 30));

        // 在检测到的人脸周围绘制矩形
        for (size_t i = 0; i < faces.size(); i++) {
            cv::Point pt1(faces[i].x, faces[i].y);
            cv::Point pt2(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
            cv::rectangle(frame, pt1, pt2, cv::Scalar(0, 255, 0), 2, 8, 0);
        }

        // 显示结果
        cv::imshow("人脸识别", frame);

        // 按下ESC键退出循环
        if (cv::waitKey(1) == 27) {
            break;
        }
    }

    // 释放摄像头和关闭窗口
    cap.release();
    cv::destroyAllWindows();

    return 0;
}
